#include "bezier.h"
#include <QDebug>
#include <qmath.h>
#include "canvas.h"

unsigned int fat(unsigned short n)
{
    unsigned int resp = 1;
    for(unsigned int i = 1; i <= n; ++i)
    {
        resp *= i;
    }
    return resp;
}

unsigned int prod(unsigned short n, unsigned short lim)
{
    unsigned int resp = 1;

    for(unsigned int i = lim; i <= n; ++i)
    {
        resp *= i;
    }
    return resp;
}


int comb(unsigned short n, unsigned short p)
{
    if(n < p) return 0;
    unsigned int num;
    unsigned int den;
    if(p > n-p)
    {
        num = prod(n,p+1);
        den = fat(n-p);
    }else
    {
        num = prod(n,n-p+1);
        den = fat(p);
    }
    return num/den;
}

Bezier::Bezier(QObject *parent) :
    QObject(parent)
{
}

void Bezier::setList(const QList<QVector2D> &list)
{
    m_list = list;
}

void Bezier::addControlPoint(const QVector2D& p)
{
    m_list.append(p);
}

QList<QVector2D> Bezier::getPolyLine(const int n)
{
    QList<QVector2D> list;

    return m_list;
}

void Bezier::getPolyLine(Canvas *canvas, const int n)
{
    canvas->drawSegment(Segment(m_list[0],m_list[1], Qt::red));
    canvas->drawSegment(Segment(m_list[1],m_list[2], Qt::black));
    canvas->drawSegment(Segment(m_list[2],m_list[3], Qt::green));

    return;
}

QList<QVector2D> Bezier::getPolyLine2(const int partes)
{
    QList<QVector2D> list;
    //return m_list;

    float dt = 1.0/partes;

    int n = m_list.size() - 1;

    for(int i = 0; i <= partes; ++i)
    {
        float t = dt*i;
        QVector2D temp;


        for(int j = 0; j < m_list.size(); ++j)
        {
            temp += comb(n,j)*pow(t, j)*pow((1.0-t), n-j)*m_list[j];
        }

        list.append(temp);
    }

    return list;
}

QList<QVector2D> Bezier::getLines()
{
    return m_list;
}
